//
//  trackDataStatistic.c
//  LAGGeometry
//
//  Created by 罗亮富 on 2018/12/18.
//

#include "trackDataStatistic.h"
#include <math.h>

#pragma mark-
#define INVALID_STATISTIC_VALUE 9999999
//计算两点之间的暂停时间 minSpeedThreshold最小平均速度阈值
double calculatePauseTimeBetweenPoint(LocationPointType p1, LocationPointType p2, double minSpeedThreshold)
{
    
    double pauseTime = 0.0;
    NSTimeInterval interval = fabs(p1.timeInterval - p2.timeInterval);
    
    if(minSpeedThreshold < 0.00001)
        return interval;
    
    
    if(interval >= AUTOPAUSE_TIME_INTERVAL)
    {
        double dis = calculateDistanceBetweenPoints(p1, p2, true);
        double avgSpeed = dis/interval;
        if (avgSpeed < minSpeedThreshold)
        {
            NSTimeInterval estimatedMoveTime = AUTOPAUSE_TIME_INTERVAL;//dis/minSpeedThreshold;
            pauseTime = (interval - estimatedMoveTime);//自动暂停时间累加
        }
    }
    
    return pauseTime;
};



void resetSegmentsStatistics(LocationPointsSegmentStatisticInfo *statis)
{
    statis->count = 0;
    statis->maxSpeed = 0;
    statis->minSpeed = 0;
    statis->totalDistance = 0;
    statis->burringDistance = 0;
    statis->goingUp = 0;
    statis->goingDown = 0;
    statis->burringGoingUp = 0;
    statis->burringGoingDown = 0;
    statis->pauseTime = 0;
    
    LocationPointType invalidPoint;
    invalidPoint.latitude = 0;
    invalidPoint.longitude = 0;
    invalidPoint.altitude = 0;
    invalidPoint.timeInterval = 0;
    invalidPoint.speed = 0;
    
    statis->firstPoint = invalidPoint;
    statis->lastPoint = invalidPoint;
    statis->lastBurringAltitudeBasePoint = invalidPoint;
    statis->lastMileageBurringAltitudeBasePoint = invalidPoint;
}

LocationPointsSegmentStatisticInfo initSegmentsStatisticsFromPoint(LocationPointType point)
{
    LocationPointsSegmentStatisticInfo statis;
    resetSegmentsStatistics(&statis);
    resetSegmentsStatisticsWithPoint(&statis,point);
    return statis;
}

void resetSegmentsStatisticsWithPoint(LocationPointsSegmentStatisticInfo *statis,LocationPointType point)
{
    statis->count = 1;
    statis->maxSpeed = point.speed;
    statis->minSpeed = point.speed;
    statis->maxAltitude = point.altitude;
    statis->minAltitude = point.altitude;
    statis->eastMostLongitude = point.longitude;
    statis->westMostLongitude = point.longitude;
    statis->southMostLatitude = point.latitude;
    statis->northMostLatitude = point.latitude;
    
    statis->firstPoint = point;
    statis->lastPoint = point;
    statis->lastBurringAltitudeBasePoint = point;
    statis->lastMileageBurringAltitudeBasePoint = point;
}

void addPointToStatistics(LocationPointsSegmentStatisticInfo *inStatistics, LocationPointType pointData)
{
    if(inStatistics->count == 0)
    {
        resetSegmentsStatisticsWithPoint(inStatistics,pointData);
        return;
    }
    
    
    LocationPointType prevPointData = inStatistics->lastPoint;
    //  LocationPointType burringAltitudeBasePoint = inStatistics->lastMileageBurringAltitudeBasePoint;
    //统计暂停时间
    inStatistics->pauseTime += calculatePauseTimeBetweenPoint(prevPointData,pointData,AUTOPAUSE_MINI_SPEED);
    
    //统计实际记录里程、累计爬升、下降
    inStatistics->totalDistance += calculateDistanceBetweenPoints(prevPointData, pointData, true);
    CLLocationDistance altitudeDelta = pointData.altitude - prevPointData.altitude;
    if (altitudeDelta >= 0.01)
        inStatistics->goingUp += altitudeDelta;
    else if (altitudeDelta <= -0.01)
        inStatistics->goingDown += -altitudeDelta;
    
    CLLocationDistance burringAltitudeDelta = pointData.altitude - inStatistics->lastBurringAltitudeBasePoint.altitude;
    if (burringAltitudeDelta >= BURRING_VAL_FOR_ALTIDUDE)
    {
        inStatistics->burringGoingUp += burringAltitudeDelta;
        inStatistics->lastBurringAltitudeBasePoint = pointData;
    }
    else if (burringAltitudeDelta <= -BURRING_VAL_FOR_ALTIDUDE)
    {
        inStatistics->burringGoingDown += -burringAltitudeDelta;
        inStatistics->lastBurringAltitudeBasePoint = pointData;
    }
    
    //统计去海拔毛刺的里程
    inStatistics->burringDistance += calculateDistanceBetweenPoints(prevPointData, pointData, false);
    CLLocationDistance disAltitudeDeltaBurring = pointData.altitude - inStatistics->lastMileageBurringAltitudeBasePoint.altitude;
    if(fabs(disAltitudeDeltaBurring) >= BURRING_VAL_FOR_ALTIDUDE)
    {
        CLLocationDistance paltDis = calculateDistanceBetweenPoints(inStatistics->lastMileageBurringAltitudeBasePoint, pointData, false);//平面距离，不统计海拔
        CLLocationDistance actualDis = calculateDistanceBetweenPoints(inStatistics->lastMileageBurringAltitudeBasePoint, pointData, true);//实际距离，统计海拔
        
        inStatistics->burringDistance += (actualDis - paltDis);//总里程加上差值
        inStatistics->lastMileageBurringAltitudeBasePoint = pointData;
    }
    
    
    if (pointData.altitude > inStatistics->maxAltitude)
        inStatistics->maxAltitude = pointData.altitude;
    
    if (pointData.altitude < inStatistics->minAltitude)
        inStatistics->minAltitude = pointData.altitude;
    
    if(pointData.longitude > inStatistics->eastMostLongitude)
        inStatistics->eastMostLongitude = pointData.longitude;
    
    if(pointData.longitude < inStatistics->westMostLongitude)
        inStatistics->westMostLongitude = pointData.longitude;
    
    if(pointData.latitude > inStatistics->northMostLatitude)
        inStatistics->northMostLatitude = pointData.latitude;
    
    if(pointData.latitude < inStatistics->southMostLatitude)
        inStatistics->southMostLatitude = pointData.latitude;
    
    
    if (pointData.speed > inStatistics->maxSpeed) {
        inStatistics->maxSpeed = pointData.speed;
    }
    
    if(pointData.speed < inStatistics->minSpeed)
        inStatistics->minSpeed = pointData.speed;
    
    inStatistics->count += 1;
    inStatistics->lastPoint = pointData;
    
}
